#include "stdafx.h"
#include "vol_user_app_info.h"

CVoliconvWrapper::~CVoliconvWrapper()
{
	if (IsValid ())
		iconv_close(m_context);
}

BOOL CVoliconvWrapper::SetContext(iconv_t iconv)
{
	if (IsValid ())
		iconv_close(m_context);
	m_context = iconv;
	return IsValid();
}

BOOL CVoliconvWrapper::VolIconv(const CVolMem& inData, CVolMem& outData, iconv_t cv)
{
	outData.Free ();

	if (cv == NULL || (INT_P)cv == -1)  // 无效的转换方式?
		return FALSE;

    if (inData.GetSize() <= 0)
		return TRUE;
	
	char* pInBuffer = (char*) inData.GetPtr();
	size_t nInBytesLeft = (size_t) inData.GetSize();
	size_t nOutBytesLeft = nInBytesLeft * 4 + 16;
	size_t nOutSize = nOutBytesLeft;
	char* pOutBuffer = (char*) outData.Alloc(nOutBytesLeft, TRUE);

	while (TRUE)
	{
		if (iconv(cv, (char**) &pInBuffer, &nInBytesLeft, &pOutBuffer, &nOutBytesLeft) != -1)
			break;
		
		if (errno == E2BIG)
		{
			nOutBytesLeft += nInBytesLeft / 2 + 1024;
			nOutSize = nOutBytesLeft;
			pOutBuffer = (char*)outData.Realloc(nOutBytesLeft);
		}
		else 
		{
			outData.Free();
			return FALSE;
		}
	}

	outData.Realloc(nOutSize - nOutBytesLeft);
	return TRUE;
}